﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MediaToolkit;
using MediaToolkit.Model;
using MediaToolkit.Options;
using System.Diagnostics;

namespace VideoSpliter.Model
{
    public class VideoSplitOperation
    {
        public MediaFile VideoFile { get; set; }

        public TimeSpan Interval { get; set; }

        public MetaData MetaData { get; set; }

        public VideoSplitOperation(TimeSpan interval, MetaData metaData)
        {
            VideoFile = new MediaFile(metaData.Path);
            Interval = interval;
            MetaData = metaData;
        }

        public event EventHandler<ProgressEventArg> ProgressUpdated;

        public string OutputDirectory { get; set; }

        private int _counter = 0;

        private int _parts = 0;

        public void Split()
        {
            using (var engine = new Engine())
            {
                _parts = (int)Math.Ceiling(MetaData.VideoData.Duration.TotalSeconds / Interval.TotalSeconds);
                TimeSpan start=TimeSpan.Zero;
                engine.ConvertProgressEvent += Engine_ConvertProgressEvent;
                var directory = Path.GetDirectoryName(VideoFile.Filename);
                var fileName = Path.GetFileNameWithoutExtension(VideoFile.Filename);
                var newDirectory = Directory.CreateDirectory(Path.Combine(directory,fileName));
                OutputDirectory = newDirectory.FullName;
                for (_counter = 0; _counter < _parts; _counter++)
                {
                    var newName = $"{fileName}_{_counter + 1}{Path.GetExtension(VideoFile.Filename)}";
                    var outputFile = new MediaFile($"{Path.Combine(newDirectory.FullName, newName)}");
                    var options = new ConversionOptions()
                    {
                        CopyVideoStream = true,
                        CopyAudioStream = true
                    };
                    options.CutMedia(start,Interval);
                    engine.Convert(VideoFile,outputFile,options);
                    start += Interval;
                }
            }
        }

        

        private void Engine_ConvertProgressEvent(object sender, ConvertProgressEventArgs e)
        {
            var previousProcessed = Interval.TotalSeconds * _counter;
            var currentProcessed = e.ProcessedDuration.TotalSeconds;
            var totalProcessed = previousProcessed + currentProcessed;
            var totalToProcess = e.TotalDuration.TotalSeconds;
            ProgressUpdated?.Invoke(this,new ProgressEventArg(totalToProcess, totalProcessed, _parts,_counter+1));
        }
    }

    public class ProgressEventArg
    {
        public double TotalToProcess { get; set; }
        public double CurrentProcessed { get; set; }
        public int TotalParts { get; set; }
        public int PartProcessing { get; set; }

        public ProgressEventArg(double totalToProcess, double currentProcessed, int totalParts, int partProcessing)
        {
            TotalToProcess = totalToProcess;
            CurrentProcessed = currentProcessed;
            TotalParts = totalParts;
            PartProcessing = partProcessing;
        }
    }
}
